package Algorithm;

import java.util.ArrayList;
import java.util.Collections;

import type.Movie;
import type.Rating;
import type.Sex;
import type.User;
import database.MovieLensDatabase;

public class Recommandations {

	public static final class RatingMoviePair implements Comparable<RatingMoviePair>
	{
		Movie movie;
		Double rating;
		Double testDataRating;
		User user;
		public RatingMoviePair(double rating, double testDataRating, Movie movie, User user)
		{
			this.rating = rating;
			this.movie = movie;
			this.testDataRating = testDataRating;
			this.user = user;
		}
		
		@Override
		public int compareTo(RatingMoviePair o) {
			return this.rating.compareTo(o.rating)*-1;
		}
	}
	
	public static void main(String [] argv)
	{
		MovieLensDatabase db = new MovieLensDatabase("..\\..\\database\\ml-100k");
		
		System.out.println("********************************");
		System.out.println("User-based ");
		System.out.println("********************************");
		for(int i=0; i<5; ++i){
			ArrayList<Rating> testRatings = db.selectRatingSet(i);
			ArrayList<RatingMoviePair> bestRecommandations = new ArrayList<RatingMoviePair>();
			for (Rating rating : testRatings) {
				double estimationResult = UserBased.estimateRating(rating.getUser(), rating.getMovie());
				bestRecommandations.add(new RatingMoviePair(estimationResult, rating.getRating(), rating.getMovie(), rating.getUser()));
			}
			Collections.sort(bestRecommandations);
			
			System.out.println("For set " + i);
			for(int n = 0; n < bestRecommandations.size() && n < 3; ++n)
			{
				System.out.println("best recommandations for user " + 
			                       bestRecommandations.get(n).user.getUserID() + ", " +
			                       bestRecommandations.get(n).user.getOccupation() + ", " +
			                       (bestRecommandations.get(n).user.getSex() == Sex.Male ? "male" : "female") + " is :");
				System.out.println(bestRecommandations.get(n).movie.getTitle() + 
			                       " with estimate rating of " + bestRecommandations.get(n).rating +
			                       " test data holds a rating of " + bestRecommandations.get(n).testDataRating);
				System.out.println();
			}
		}
		
		System.out.println("********************************");
		System.out.println("Item-based ");
		System.out.println("********************************");
		for(int i=0; i<5; ++i){
			ArrayList<Rating> testRatings = db.selectRatingSet(i);
			ArrayList<RatingMoviePair> bestRecommandations = new ArrayList<RatingMoviePair>();
			for (Rating rating : testRatings) {
				double estimationResult = ItemBased.estimateRating(rating.getUser(), rating.getMovie());
				bestRecommandations.add(new RatingMoviePair(estimationResult, rating.getRating(), rating.getMovie(), rating.getUser()));
			}
			Collections.sort(bestRecommandations);
			
			System.out.println("For set " + i);
			for(int n = 0; n < bestRecommandations.size() && n < 3; ++n)
			{
				System.out.println("best recommandations for user " + 
			                       bestRecommandations.get(n).user.getUserID() + ", " +
			                       bestRecommandations.get(n).user.getOccupation() + ", " +
			                       (bestRecommandations.get(n).user.getSex() == Sex.Male ? "male" : "female") + " is :");
				System.out.println(bestRecommandations.get(n).movie.getTitle() + 
			                       " with estimate rating of " + bestRecommandations.get(n).rating +
			                       " test data holds a rating of " + bestRecommandations.get(n).testDataRating);
				System.out.println();
			}
		}		
	}
}
